From 2ba5c5ec454a2a3b0f4711c685c60822b7027d70 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Sun, 23 Nov 2014 17:46:04 -0800 Subject: [PATCH] Test source equality when locking dependencies When applying the lockfile to a resolve graph, we need to take into account that the listed source of dependencies can change over time, in which case we cannot lock to the previous version but instead need to continue onwards with updating the listed source. Closes #951 --- src/cargo/core/registry.rs | 27 +++++++++-- tests/test_cargo_compile_git_deps.rs | 69 ++++++++++++++++++++++++++++ 2 files changed, 91 insertions(+), 5 deletions(-) diff --git a/src/cargo/core/registry.rs b/src/cargo/core/registry.rs index 39dba008f..ed0042863 100644 --- a/src/cargo/core/registry.rs +++ b/src/cargo/core/registry.rs @@ -226,13 +226,30 @@ impl<'a> PackageRegistry<'a> { }; summary.map_dependencies(|dep| { match pair { - // If this summary has a locked version, then we need to lock - // this dependency. If this dependency doesn't have a locked - // version, then it was likely an optional dependency which - // wasn't included and we just pass it through anyway. + // If we've got a known set of overrides for this summary, then + // one of a few cases can arise: + // + // 1. We have a lock entry for this dependency from the same + // source as its listed as coming from. In this case we make + // sure to lock to precisely the given package id. + // + // 2. We have a lock entry for this dependency, but it's from a + // different source than what's listed. In this case we must + // discard the locked version because the listed source must + // have changed. + // + // 3. We don't have a lock entry for this dependency, in which + // case it was likely an optional dependency which wasn't + // included previously so we just pass it through anyway. Some(&(_, ref deps)) => { match deps.iter().find(|d| d.get_name() == dep.get_name()) { - Some(lock) => dep.lock_to(lock), + Some(lock) => { + if lock.get_source_id() == dep.get_source_id() { + dep.lock_to(lock) + } else { + dep + } + } None => dep, } } diff --git a/tests/test_cargo_compile_git_deps.rs b/tests/test_cargo_compile_git_deps.rs index 5972630e0..dbb846703 100644 --- a/tests/test_cargo_compile_git_deps.rs +++ b/tests/test_cargo_compile_git_deps.rs @@ -1563,3 +1563,72 @@ test!(update_one_source_updates_all_packages_in_that_git_source { assert!(!lockfile.as_slice().contains(rev1.to_string().as_slice()), "{} in {}", rev1, lockfile); }) + +test!(switch_sources { + let a1 = git_repo("a1", |project| { + project.file("Cargo.toml", r#" + [package] + name = "a" + version = "0.5.0" + authors = [] + "#) + .file("src/lib.rs", "") + }).assert(); + let a2 = git_repo("a2", |project| { + project.file("Cargo.toml", r#" + [package] + name = "a" + version = "0.5.1" + authors = [] + "#) + .file("src/lib.rs", "") + }).assert(); + + let p = project("project") + .file("Cargo.toml", r#" + [project] + name = "project" + version = "0.5.0" + authors = [] + [dependencies.b] + path = "b" + "#) + .file("src/main.rs", "fn main() {}") + .file("b/Cargo.toml", format!(r#" + [project] + name = "b" + version = "0.5.0" + authors = [] + [dependencies.a] + git = '{}' + "#, a1.url()).as_slice()) + .file("b/src/lib.rs", "fn main() {}"); + + p.build(); + assert_that(p.process(cargo_dir().join("cargo")).arg("build"), + execs().with_status(0) + .with_stdout(format!("\ +{updating} git repository `file://[..]a1` +{compiling} a v0.5.0 ([..]a1#[..] +{compiling} b v0.5.0 ([..]) +{compiling} project v0.5.0 ([..]) +", updating = UPDATING, compiling = COMPILING).as_slice())); + + File::create(&p.root().join("b/Cargo.toml")).write_str(format!(r#" + [project] + name = "b" + version = "0.5.0" + authors = [] + [dependencies.a] + git = '{}' + "#, a2.url()).as_slice()).unwrap(); + + assert_that(p.process(cargo_dir().join("cargo")).arg("build"), + execs().with_status(0) + .with_stdout(format!("\ +{updating} git repository `file://[..]a2` +{compiling} a v0.5.1 ([..]a2#[..] +{compiling} b v0.5.0 ([..]) +{compiling} project v0.5.0 ([..]) +", updating = UPDATING, compiling = COMPILING).as_slice())); +}) -- 2.30.2